import { OrganizationTreeService } from './../../service/organizationTreeService';
import { AccountRolesService } from './../../service/accountRolesService';
import * as Koa from 'koa';
import { Transaction } from 'tiny-entity2';
import { Guid, route, RouteOptionsVerify, ServiceManager } from "../../common";
// import { ServiceException } from '../../common/excpetion';
import { ApiDataContext } from '../../domain/apiDataContext';
import { AccountPermits } from '../../domain/models/accountPermits';
import { AccountPermitsService } from '../../service/AccountPermitsService';
import Enumerable = require('linq');

const actPermitsSvr = ServiceManager.Current.GetService<AccountPermitsService>('AccountPermitsService');
const arSvr = ServiceManager.Current.GetService<AccountRolesService>('AccountRolesService');
const tSvr = ServiceManager.Current.GetService<OrganizationTreeService>('OrganizationTreeService');

class AccountPermitsController {
    @route(new RouteOptionsVerify('GET', '/api/accountpermits'))
    async queryAccountPermitss(ctx: Koa.Context, next) {
        let params = ctx.query;
        let data = await actPermitsSvr.QueryAccountPermits(params);

        let permitsTmp: AccountPermits[] = [];
        for (let item of data) {
            let has = permitsTmp.find(x => x.permitName == item.permitName && x.authObjectId == item.authObjectId && x.refObjectId == item.refObjectId);
            if (!has) {
                permitsTmp.push(item);
            }
        }

        ctx.response.body = permitsTmp;
        await next();
    }

    @route(new RouteOptionsVerify('POST', '/api/accountpermits'))
    async createAccountPermits(ctx: Koa.Context, next) {
        let orgId = ctx.headers['orgid'];
        let { authObjectId, authObjectType } = ctx.query;
        let permits: AccountPermits[] = ctx.request.body;
        // if (!permits || permits.length <= 0) {
        //     throw new ServiceException("添加的权限不能为空", "not_be_null");
        // }

        if (!authObjectId) {
            authObjectId = permits[0].authObjectId;
        }

        let permitsTmp: AccountPermits[] = [];
        for (let item of permits) {
            let has = permitsTmp.find(x => x.permitName == item.permitName && x.authObjectId == item.authObjectId && x.refObjectId == item.refObjectId);
            if (!has) {
                permitsTmp.push(item);
            }
        }

        permits = permitsTmp;

        await Transaction(new ApiDataContext(), async datactx => {
            await actPermitsSvr.DeleteAccountPermitsByAuthObjectId(authObjectId);

            for (let i = 0; i < permits.length; i++) {
                permits[i].id = Guid.GetGuid();
                permits[i].orgId = orgId;
            }

            await actPermitsSvr.CreateAccountPermits(permits, datactx);
        });
        ctx.response.body = permits;
        await next();
    }

    @route(new RouteOptionsVerify('DELETE', '/api/accountpermits'))
    async deleteAccountPermits(ctx: Koa.Context, next) {
        let params = ctx.query;
        let data = await actPermitsSvr.DeleteAccountPermits(params);
        ctx.response.body = data;
        await next();
    }

    @route(new RouteOptionsVerify('GET', '/api/user/:userId/account/:accountId/accountpermits'))
    async getUserPermits(ctx: Koa.Context, next) {
        let { accountId, userId } = ctx.params;

        let result: AccountPermits[] = [];
        let roles = await arSvr.QueryAccountRoles({ accountId });

        for (let item of roles) {
            let r = await actPermitsSvr.QueryAccountPermits({
                authObjectId: item.roleId
            });

            result = result.concat(r);
        }

        let r = await actPermitsSvr.QueryAccountPermits({
            authObjectId: userId
        });
        result = result.concat(r);

        let userNode = await tSvr.GetOrgTreeNodeByObjectId(userId);

        if (userNode) {
            let departmentNode = await tSvr.GetOrganizationTreeById(userNode.parentId);
            if (departmentNode) {
                let r = await actPermitsSvr.QueryAccountPermits({
                    authObjectId: departmentNode.objectId
                });

                result = result.concat(r);
            }
        }


        ctx.response.body = result; //Enumerable.from(result).distinct(x => x.refObjectId && x.permitId).toArray();

        await next();
    }
}